#include<iostream>
#include<fstream>
#include<stdlib.h>
#include<string>
using namespace std;
struct Student
{
	int id;
    char name[20];
    float score;
};
void Addrecord(const string &filename)
{
	ofstream file(filename,ios::binary|ios::app);
	if(!file)
	{
		cout << "文件打开失败" <<endl;
		exit(0);
	}
	Student s;
	cout << "请输入姓名 ：" ;
	cin.ignore();
	cin.getline(s.name,20);
	cout << "请输入学号 ：" ;
	cin >> s.id;
	cout << "请输入成绩 ：" ;
	cin >> s.score;
	file.write(reinterpret_cast<const char*>(&s), sizeof(Student));
	file.close();
	cout << "记录添加成功。"<<endl;
}
void Displayrecord(const string &filename)
{
	fstream file(filename,ios::binary|ios::in);
	if(!file)
	{
		cout << "文件打开失败" <<endl;
		exit(0);
	}
	Student s;
	int count=0;
	cout << "\n======= 所有学生记录 =======" << endl;
	 while (file.read(reinterpret_cast<char*>(&s), sizeof(Student))) 
	{
        cout << "\n姓名: " << s.name << endl;
    	cout << "学号: " << s.id<< endl;
    	cout << "成绩: " << s.score << endl;
        cout << "--------------------------" << endl;
        count++;
    }
    if(count == 0) 
	{
        cout << "没有找到任何记录！" << endl;
    }
	file.close();
}
void Searchrecord(const string &filename)
{
	fstream file(filename,ios::binary|ios::in);
	if(!file)
	{
		cout << "文件打开失败" <<endl;
		exit(0);
	}
	string family_name;
	cout << "请输入要查找的姓氏：" ;
	cin >> family_name;
	Student s;
	int count=0;
	while (file.read(reinterpret_cast<char*>(&s), sizeof(Student)))
	{
		if (strncmp(s.name, family_name.c_str(), family_name.length())==0) 
		{
			cout << "姓名: " << s.name << endl;
            cout << "学号: " << s.id << endl;
            cout << "成绩: " << s.score << endl;
            cout << "-------------------------" << endl;
            count++;
		}
	}
	if(count==0)
	cout << "未找到该姓氏学生"<< endl;
	file.close();
}
void Changerecord(const string &filename)
{
	fstream file(filename,ios::binary|ios::in|ios::out);
	if(!file)
	{
		cout << "文件打开失败" <<endl;
		exit(0);
	}
	string changename;
	cout << "请输入要修改的学生姓名：" ;
	cin.ignore();
	cin >> changename;
	bool found=false;
	long pos=0;
	Student s;
	while (file.read(reinterpret_cast<char*>(&s), sizeof(Student)))
	{
		if (strcmp(s.name, changename.c_str()) == 0)
		{
			found=true;
			pos = file.tellg();
            pos -= sizeof(Student);
			break;
		}
	}
	if(found)
	{
		cout << "找到记录，开始修改..." << endl;
        cout << "请输入新的姓名: ";
        cin.ignore();
		cin.getline(s.name,20);
        cout << "请输入学号 ：" ;
		cin >> s.id;
		cout << "请输入新的成绩 ：" ;
		cin>> s.score;
		file.seekp(pos);
		file.write(reinterpret_cast<const char*>(&s), sizeof(Student));
		cout << "记录修改成功。";
	}
	else
	{
		cout << "未找到指定学生" <<endl;
	}
	file.close();
}
void Deleterecord(const string &filename)
{
	fstream file(filename,ios::binary|ios::in);
	if(!file)
	{
		cout << "文件打开失败" <<endl;
		exit(0);
	}
	fstream temp("temp.dat",ios::binary|ios::out);
	if(!temp)
	{
		cout << "文件打开失败" <<endl;
		exit(0);
	}
	string target;
	cout << "请输入要删除的学生姓名：";
	cin.ignore();
	cin >> target;
	Student s;
	bool found=false;
	while(file.read(reinterpret_cast<char*>(&s), sizeof(Student)))
	{
		if(strcmp(s.name, target.c_str()) != 0)
		{
			temp.write(reinterpret_cast<const char*>(&s), sizeof(Student));
		}
		else
		found =true;
	}
	file.close();
    temp.close();
    if(found) 
	{
        remove(filename.c_str());
        rename("temp.dat", filename.c_str());
        cout << "记录删除成功！" << endl;
    } 
	else 
	{
        remove("temp.dat");
        cout << "未找到该学生记录！" << endl;
    }
}
int main()
{
	string filename="student.dat";
	int choice;
	while(true)
	{
		cout << "请输入操作选项：" <<endl;
		cout << "1.增加学生数据" <<endl;
		cout << "2.显示全部学生数据" <<endl;
		cout << "3.用姓氏查找学生" <<endl;
		cout << "4.对指定学生的数据进行修改" <<endl;
		cout << "5.删除指定学生的数据" <<endl;
		cout << "6.退出系统" <<endl;
		cout << "请选择操作: ";
		cin >> choice;
		if(cin.fail())
		{
			cin.clear();
			cin.ignore();
			cout << "输入无效，请重新输入数字选项" <<endl;
			continue;
		}
		switch(choice)
		{
			case 1:
				Addrecord(filename);
				break;
			case 2:
				Displayrecord(filename);
				break;
			case 3:
				Searchrecord(filename);
				break;
			case 4:
				Changerecord(filename);
				break;
			case 5:
				Deleterecord(filename);
				break;
			case 6:
				return 0;
			default:
				cout << "无效选择，请重新输入" << endl;
		}
	}
	return 0;
}